package edu.hawaii.myisern.action;

import java.io.IOException;
import java.math.BigInteger;
import javax.xml.bind.JAXBException;
import edu.hawaii.myisern.collaborations.jaxb.CollaboratingOrganizations;
import edu.hawaii.myisern.collaborations.jaxb.Collaboration;
import edu.hawaii.myisern.collaborations.jaxb.CollaborationTypes;
import edu.hawaii.myisern.collaborations.jaxb.OutcomeTypes;
import edu.hawaii.myisern.collaborations.jaxb.Years;
import edu.hawaii.myisern.model.MyIsernModel;
import net.sourceforge.stripes.action.DefaultHandler;
import net.sourceforge.stripes.action.DontValidate;
import net.sourceforge.stripes.action.ForwardResolution;
import net.sourceforge.stripes.action.Resolution;
import net.sourceforge.stripes.validation.SimpleError;
import net.sourceforge.stripes.validation.Validate;
import net.sourceforge.stripes.validation.ValidationError;

/**
 * Handles the Adding of a new collaboration
 * 
 * @author phillip le
 * @author Sonwright M. Gomez
 * 
 */
public class EditCollaborationActionBean extends MyIsernActionBean {

  /** The singleton MyIsernModel. */
  private MyIsernModel myIsern = MyIsernModel.getInstance();
  private Collaboration collaboration;
  
  /** The Collaboration name,which is required. */
  @Validate(required = true)
  private String collaborationName;
  private String collaborationOrgs;
  private String collaborationTypes;
  private String collaborationYears;
  private String collaborationOutcomes;
  private String collaborationDescription;
  private String possibleCollaborationName;
  private String errorMessage;
  private String mainMenu = "/mainMenu.jsp";
  private String oldCollaborationName;
  
  /**
   * Get's the possible name.
   * 
   * @return possibleCollaborationName The possible name.
   */
  public String getPossibleCollaborationName() {
    return possibleCollaborationName;
  }

  /**
   * Set's possible name.
   * 
   * @param name containing name.
   */
  public void setPossibleCollaborationName(String name) {
    this.possibleCollaborationName = name;
  }
  /**
   * Set's the collaboration name.
   * 
   * @param cName the name of the collaboration.
   */
  public void setCollaborationName(String cName) {
    this.collaborationName = cName;
  }

  /**
   * Get's the collab name.
   * 
   * @return collaborationName The collab name.
   */
  public String getCollaborationName() {
    return collaborationName;
  }

  /**
   * Set's the list of collaborating organizations.
   * 
   * @param cOrgs the string of collaborating orgs.
   */
  public void setCollaborationOrgs(String cOrgs) {
    this.collaborationOrgs = cOrgs;
  }

  /**
   * Get's the collab org.
   * 
   * @return collaborationOrgs list of collaborating organizations.
   */
  public String getCollaborationOrgs() {
    return collaborationOrgs;
  }

  /**
   * Set's the list of collaboration types.
   * 
   * @param cTypes the list of collaborating types.
   */
  public void setCollaborationTypes(String cTypes) {
    this.collaborationTypes = cTypes;
  }

  /**
   * Get's the collab types.
   * 
   * @return collaborationTypes list of collaboration types.
   */
  public String getCollaborationTypes() {
    return collaborationTypes;
  }

  /**
   * Set's the list of collaborating years
   * 
   * @param cYears the list of years of collaboration
   */
  public void setCollaborationYears(String cYears) {
    this.collaborationYears = cYears;
  }

  /**
   * Get's the collab collaboration years
   * 
   * @return collaborationYears lists the years of collaborations.
   */
  public String getCollaborationYears() {
    return collaborationYears;
  }

  /**
   * Set's the list of collaboration outcomes
   * 
   * @param cOutcomes the outcomes of the collaborations
   */
  public void setCollaborationOutcomes(String cOutcomes) {
    this.collaborationOutcomes = cOutcomes;
  }

  /**
   * Get's the collab outcomes
   * 
   * @return collaborationOutcomes the outcomes of the collaborations.
   */
  public String getCollaborationOutcomes() {
    return collaborationOutcomes;
  }

  /**
   * Set's the collaboration descriptoin
   * 
   * @param cDescription which is the collab's description.
   */
  public void setCollaborationDescription(String cDescription) {
    this.collaborationDescription = cDescription;
  }

  /**
   * Get's the collab description.
   * 
   * @return collaborationDescriptoin Description of the collaboration
   */
  public String getCollaborationDescription() {
    return collaborationDescription;
  }

  /**
   * Set's the error message for the user.
   * 
   * @param errorMessage containing error Message. 
   */
  public void setErrorMessage(String errorMessage) {
    this.errorMessage = errorMessage;
  }
  
  /**
   * Returns the error message, which may be empty.
   * 
   * @return The error message. 
   */
  public String getErrorMessage() {
    return this.errorMessage;
  }
  
  /**
   * Loads pre-edited Collaboration to textfields.
   * 
   * @return Resoluton to redisplay a jsp page.
   */
  @DontValidate
  public Resolution preEditCollaboration() {
    try {
      if (myIsern.getCollaborationIds().contains
          (getPossibleCollaborationName().replace(' ', '_').toLowerCase())) {
        this.collaboration = this.myIsern.getCollaboration(this.possibleCollaborationName);
        this.oldCollaborationName = getPossibleCollaborationName();
        setCollaborationName(this.collaboration.getName());
        setCollaborationOrgs(myIsern.coToString
            (this.collaboration.getCollaboratingOrganizations()));
        setCollaborationTypes(myIsern.ctToString(this.collaboration.getCollaborationTypes()));
        setCollaborationYears(myIsern.yearsToString(this.collaboration.getYears()));
        setCollaborationOutcomes(myIsern.otToString(this.collaboration.getOutcomeTypes()));
        setCollaborationDescription(this.collaboration.getDescription().trim());
        return new ForwardResolution("/editCollaboration.jsp");
      }
      else {
        setErrorMessage("There was no match found in the Collaboration " +
            "database. Please check spelling for any errors.");
        return new ForwardResolution ("/findCollaboration.jsp");
      }
    }
    catch (NullPointerException e) {
      setErrorMessage("Collaboration field blank");
      return new ForwardResolution("/findCollaboration.jsp");
    }
  }
  
  /**
   * A handler that performs the action when the 'login' button is pressed.
   * 
   * @return A Resolution indicating to display the mainMenu.jsp page.
   * @throws IOException If IO error occurs
   * @throws JAXBException if JAXB error occurs
   */
  @DefaultHandler
  public Resolution submitAndSave() throws JAXBException, IOException {
    this.oldCollaborationName = this.collaborationName;
    String delim = "," + "\\s";
    if (getCollaborationName().isEmpty()) {
      ValidationError error = new SimpleError("Requires a Collaboration Name");
      getContext().getValidationErrors().add("collaborationName", error);
      return getContext().getSourcePageResolution();
    }
    else {
      // Adds new Collaboration name
      Collaboration newC = new Collaboration();
      newC.setName(this.collaborationName);

      // Adds Collaborating Organizations
      CollaboratingOrganizations newOrgs = new CollaboratingOrganizations();
      try {
        String[] tempCollabOrg = this.collaborationOrgs.split(delim);
        for (String curr : tempCollabOrg) {
          newOrgs.getCollaboratingOrganization().add(curr.trim());
        }
      }
      catch (NullPointerException e) {
        newOrgs.getCollaboratingOrganization().add("");

      }
      newC.setCollaboratingOrganizations(newOrgs);

      // Add Collaboration types
      CollaborationTypes newTypes = new CollaborationTypes();
      try {
        String[] tempCollabTypes = this.collaborationTypes.split(delim);
        for (String curr : tempCollabTypes) {
          newTypes.getCollaborationType().add(curr.trim());
        }
      }
      catch (NullPointerException e) {
        newOrgs.getCollaboratingOrganization().add("");
      }
      newC.setCollaborationTypes(newTypes);

      // Add Collaboration years

      Years newYears = new Years();
      try {
        String[] tempYears = this.collaborationYears.split(delim);
        int i = 0;
        for (String curr : tempYears) {
          if (myIsern.yearIsValid(curr.trim())) {
            try {
              BigInteger bigNum = new BigInteger(curr.trim());
              newYears.getYear().add(bigNum);
              i++;
            }
            catch (NumberFormatException e) {
              e.printStackTrace();
            }
          }
        }
        if (i == 0) {
          BigInteger temp = new BigInteger("1990");
          newYears.getYear().add(temp);
        }
      }
      catch (NullPointerException e) {
        BigInteger bigNum = new BigInteger("1990");
        newYears.getYear().add(bigNum);
      }
      newC.setYears(newYears);

      // Add Collaboration outcomes
      OutcomeTypes newOutcomeTypes = new OutcomeTypes();
      try {
        String[] tempOutcomeTypes = this.collaborationOutcomes.split(delim);
        for (String curr : tempOutcomeTypes) {
          newOutcomeTypes.getOutcomeType().add(curr.trim());
        }
      }
      catch (NullPointerException e) {
        newOutcomeTypes.getOutcomeType().add("");
      }
      newC.setOutcomeTypes(newOutcomeTypes);

      // Add collaboration description
      try {
        newC.setDescription(this.collaborationDescription);
      }
      catch (NullPointerException e) {
        newC.setDescription("");
      }
      myIsern.deleteCollaboration(this.oldCollaborationName);
      myIsern.addCollaboration(newC);
      myIsern.saveCollaboration();

      return new ForwardResolution("/mainMenu.jsp");
    }

  }

  /**
   * Goes back to the main menu without saving anything.
   * 
   * @return a resolution to display the main menu.
   */
  @DontValidate
  public Resolution cancel() {
    return new ForwardResolution("/mainMenu.jsp");
  }

}
